/*
*	Copyright (C) 2014  Julio Montes, Mario Carrillo
*	
*	Julio Montes e-mail: imc.coder@gmail.com 
*
*	Mario Carrillo e-mail: mario_90ago@live.com.mx
*
*	BSD 3-Clause License
*/

#include "alliance/include/optionctrl.h"
#include "sdk/include/util.h"
#include <wx/tokenzr.h>

#define CHECKBOX_ID 1001
#define COMBOBOX_ID 1002
#define TEXTCTRL_ID 1003

namespace alliance
{
    OptionCtrl::OptionCtrl( wxWindow *parent, wxWindowID id )
        : ToolCtrl( parent, id )
        , m_checkBox( NULL )
        , m_textCtrl( NULL )
        , m_comboBox( NULL )
        , m_empty( true )
        , m_dependencies( wxEmptyString )
    {
        Connect( CHECKBOX_ID, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( OptionCtrl::OnCheckBox ) );
    }

    OptionCtrl::~OptionCtrl()
    {

    }

    bool OptionCtrl::Load( const sdk::vectorAttributesString &vectorAttributes )
    {
        wxString l_checkText;
        bool l_hasComboBox = false;
        bool l_hasTextCtrl = false;
        bool l_checked = false;
        bool l_editable = true;
        wxString l_args;
        wxString l_defaultarg;
        for( size_t i=0; i<vectorAttributes.size(); ++i )
        {
            const wxString &l_name = vectorAttributes[i].name;

            if( 0 == l_name.Cmp( wxT( "opt" ) ) )
            {
                m_key = vectorAttributes[i].value;
            }
            else if( 0 == l_name.Cmp( wxT( "descr" ) ) )
            {
                l_checkText = vectorAttributes[i].value;
                l_checkText.Replace( wxT( "\\n" ), wxT( "\n" ) );
            }
            else if( 0 == l_name.Cmp( wxT( "empty" ) ) )
            {
                l_hasTextCtrl = true;
                m_empty = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == l_name.Cmp( wxT( "editable" ) ) )
            {
                l_hasTextCtrl = true;
                l_editable = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == l_name.Cmp( wxT( "checked" ) ) )
            {
                l_checked = sdk::stringToBool( vectorAttributes[i].value );
            }
            else if( 0 == l_name.Cmp( wxT( "args" ) ) )
            {
                l_hasComboBox = true;
                l_args = vectorAttributes[i].value;
            }
            else if( 0 == l_name.Cmp( wxT( "defaultarg" ) ) )
            {
                l_hasTextCtrl = true;
                l_defaultarg = vectorAttributes[i].value;
            }
            else if( 0 == l_name.Cmp( wxT( "dependencies" ) ) )
            {
                m_dependencies = vectorAttributes[i].value;
            }
        }

        if( m_key.IsEmpty() )
            return false;

        wxBoxSizer *l_boxSizer = new wxBoxSizer( wxHORIZONTAL );
        m_checkBox = new wxCheckBox( this, CHECKBOX_ID, wxT( "(") + m_key + wxT( ") " ) + l_checkText );
        m_checkBox->SetValue( l_checked );
        l_boxSizer->Add( m_checkBox, 0, wxLEFT | wxRIGHT, 10 );

        if( l_hasComboBox )
        {
            wxArrayString l_arrayString;
            wxStringTokenizer st( l_args, wxT( "," ), wxTOKEN_STRTOK );
            while( st.HasMoreTokens() )
            {
                l_arrayString.Add( st.GetNextToken() );
            }
            m_comboBox = new wxComboBox( this, COMBOBOX_ID, l_defaultarg, wxDefaultPosition,
                wxDefaultSize, l_arrayString, ( l_editable ? 0 : wxCB_READONLY ) );
            m_comboBox->Enable( l_checked );
            l_boxSizer->Add( m_comboBox, 0, wxLEFT | wxRIGHT, 5 );
        }
        else if( l_hasTextCtrl )
        {
            m_textCtrl = new wxTextCtrl( this, TEXTCTRL_ID, l_defaultarg, wxDefaultPosition,
                wxDefaultSize, ( l_editable ? 0 : wxTE_READONLY ) );
            m_textCtrl->Enable( l_checked );
            l_boxSizer->Add( m_textCtrl, 0, wxLEFT | wxRIGHT, 5 );
        }

        SetSizer( l_boxSizer );

        return true;
    }

    bool OptionCtrl::IsOk() const
    {
        if( !m_checkBox->IsChecked() )
        {
            return true;
        }

        if( m_textCtrl != NULL )
        {
            if( m_textCtrl->GetValue().IsEmpty() && !m_empty )
            {
                wxMessageBox( wxT( "The field of the option " ) + m_key + wxT( " is empty" ), wxT( "Error" ), wxICON_ERROR );
                m_textCtrl->SetFocus();
                return false;
            }
        }

        if( m_comboBox != NULL )
        {
            if( m_comboBox->GetValue().IsEmpty() && !m_empty )
            {
                wxMessageBox( wxT( "The field of the option " ) + m_key + wxT( " is empty" ), wxT( "Error" ), wxICON_ERROR );
                m_comboBox->SetFocus();
                return false;
            }
        }

        return true;
    }

    void OptionCtrl::AddDependency( OptionCtrl *dependency )
    {
        m_vectorDependencies.push_back( dependency );
        dependency->Connect( CHECKBOX_ID, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( OptionCtrl::OnCheckBoxDependency ), NULL, this );
    }

    void OptionCtrl::CheckDependencies()
    {
        for( size_t i=0; i<m_vectorDependencies.size(); ++i )
        {
            if( !m_vectorDependencies[i]->IsChecked() )
            {
                Enable( false );
                return;
            }
        }

        Enable( true );
    }

    bool OptionCtrl::IsChecked() const
    {
        return m_checkBox->GetValue();
    }

    void OptionCtrl::Checked( bool checked )
    {
        m_checkBox->SetValue( checked );
        if( m_comboBox != NULL )
        {
            m_comboBox->Enable( checked );
        }
        else if( m_textCtrl != NULL )
        {
            m_textCtrl->Enable( checked );
        }
    }

    wxString OptionCtrl::GetText() const
    {
        if( m_textCtrl != NULL )
        {
            return m_textCtrl->GetValue();
        }
        if( m_comboBox != NULL )
        {
            return m_comboBox->GetValue();
        }

        return wxEmptyString;
    }

    void OptionCtrl::SetText( const wxString &text )
    {
        if( m_textCtrl != NULL )
        {
            m_textCtrl->SetValue( text );
        }
        else if( m_comboBox != NULL )
        {
            m_comboBox->SetValue( text );
        }
    }

    void OptionCtrl::OnCheckBox( wxCommandEvent &evt )
    {
        if( m_comboBox != NULL )
        {
            m_comboBox->Enable( evt.IsChecked() );
        }
        else if( m_textCtrl != NULL )
        {
            m_textCtrl->Enable( evt.IsChecked() );
        }

        evt.Skip();
    }

    void OptionCtrl::OnCheckBoxDependency( wxCommandEvent &evt )
    {
        CheckDependencies();
        evt.Skip();
    }
}
